﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace DeviceSimulation
{
    public class TcpClientMana
    {
        public Socket tcpClient;
        public string numstr;
        public bool flag;
        public string deviceID;
    }

    public class CClient
    {
        /// <summary>
        /// 当前电脑的IP
        /// </summary>
        static public string hostIp = "192.168.0.102";
        /// <summary>
        /// 线程管理
        /// </summary>
        static public Dictionary<string,Thread> _threadMana = new Dictionary<string, Thread>();

        static public object sendlock = new object();

        //static public List<TcpClientMana> _tcMana = new List<TcpClientMana>();
        /// <summary>
        /// DIO索引
        /// </summary>
        static Dictionary<string, int> DIOindex = new Dictionary<string, int>();
        static public string[] _deviceID = null;

        #region 获取当前电脑IP
        /// <summary>
        /// 获取当前电脑IP
        /// </summary>
        static public void GetCurrentComputerIP()
        {
            //获取当前电脑IP
            IPHostEntry hostEntry = Dns.GetHostEntry("");
            foreach (IPAddress address in hostEntry.AddressList)
            {
                if (address.AddressFamily == AddressFamily.InterNetwork)
                {
                    hostIp = address.ToString();
                    break;
                }
            }
        }
        #endregion

        /// <summary>
        /// 将所有ID读入
        /// </summary>
        static public void ReadDeviceID()
        {
            string FileName = "DeviceID.txt";
            _deviceID = File.ReadAllLines(FileName);

            foreach (string str in _deviceID)
            {
                Console.WriteLine(str);
            }
        }

        /// <summary>
        /// 连接服务器
        /// </summary>
        static public void LinkServer()
        {
            Console.WriteLine("将要模拟的设备数量为:" + (_deviceID.Length).ToString());

            Console.WriteLine("请输入服务器的IP地址，如果用192.168.0.102地址直接回车即可：");
            string ip = Console.ReadLine();

            if (ip != "")
                hostIp = ip;
            else
                hostIp = "121.196.201.131";
            
            Console.WriteLine("服务器IP为："+ hostIp);

            //for(int i=0;i< _deviceID.Length; i++)
            int i = 0;
            foreach(string deviceID in _deviceID )
            {
                
                //定义一个套接字监听  
                Socket socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //获取文本框中的IP地址  
                IPAddress address = IPAddress.Parse( hostIp);

                //将获取的IP地址和端口号绑定在网络节点上  
                IPEndPoint point = new IPEndPoint(address, 7815);

                try
                {
                    socketclient.Connect(point);

                    int DIOStatus = 0;
                    DIOindex.Add(socketclient.LocalEndPoint.ToString(), DIOStatus);

                    TcpClientMana tcm = new TcpClientMana();
                    tcm.flag = false;
                    Thread th = new Thread(TCPClientThreadNew);
                    tcm.tcpClient = socketclient;
                    tcm.numstr = i.ToString();
                    tcm.deviceID = deviceID;
                    _threadMana.Add(tcm.numstr, th);
                    th.IsBackground = true;
                    th.Start(tcm);
                    Console.WriteLine("已创建的线程数为：" + (i+1).ToString());
                    
                    i++;
                }
                catch {
                    Console.WriteLine("连接失败。。。");
                }

                //Thread.Sleep(200);
            }
        }

        /// <summary>
        /// TCP客户端线程
        /// </summary>
        /// <param name="clientObj"></param>
        /// <param name="numObj"></param>
        static public void TCPClientThreadNew(object clientObj)
        {
            TcpClientMana tcm = clientObj as TcpClientMana;
            Socket tcpClient = tcm.tcpClient;
            string numstr = tcm.numstr;
            byte[] buffer = new byte[256];
            int dataLen = 0;

            while (true)
            {
                try
                {
                    dataLen = tcpClient.Receive(buffer);
                    if (dataLen == 0) break;
                    string rATCmd = MyConvert.AsciiByteToString(buffer, dataLen);
                    Console.WriteLine(tcpClient.LocalEndPoint.ToString() + "接收：" + rATCmd);

                    if(rATCmd.Contains("AT+WID=?") == true)
                    {
                        string strcmd = "+WID:" + tcm.deviceID + "\r\n";
                        byte[] sendData = MyConvert.StringToByteArray(strcmd);
                        tcpClient.Send(sendData);
                        Thread.Sleep(500);
                        string strcmd1 = "AT\r\n";
                        byte[] sendData1 = MyConvert.StringToByteArray(strcmd1);
                        tcpClient.Send(sendData1);
                    }
                    else if(rATCmd.Contains("AT+ACK") == true)
                    {
                        Thread.Sleep(3000);
                        string cmd = "AT\r\n";
                        byte[] sData = MyConvert.StringToByteArray(cmd);
                        tcpClient.Send(sData);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    _threadMana.Remove(tcm.numstr);
                    tcm.tcpClient.Close();
                    Thread.CurrentThread.Abort();
                }
            }
        }

        static public void TCPClientThreadSendNew(object clientObj)
        {
            TcpClientMana tcm = clientObj as TcpClientMana;
            Socket tcpClient = tcm.tcpClient;
            
            string cmdStr = "";

            while (true)
            {
                try
                {
                    cmdStr = "Device Number:" + (tcm.numstr + 1).ToString();
                    byte[] buf = MyConvert.StringToAsciiByte(cmdStr);
                    tcpClient.Send(buf);
                    tcm.flag = true;

                    Thread.Sleep(500);
                }
                catch
                {

                }
            }
        }
    }
}
